package chd.edu.train.member.service;

import chd.edu.train.common.exception.BusinessException;
import chd.edu.train.common.exception.BusinessExceptionEnum;
import chd.edu.train.common.util.JwtUtil;
import chd.edu.train.common.util.SnowUtil;
import chd.edu.train.member.domain.Member;
import chd.edu.train.member.domain.MemberExample;
import chd.edu.train.member.mapper.MemberMapper;
import chd.edu.train.member.req.MemberLoginReq;
import chd.edu.train.member.req.MemberRegisterReq;
import chd.edu.train.member.req.MemberSendCodeReq;
import chd.edu.train.member.resp.MemberLoginResp;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Zhang Chaoliang
 * create 2023
 */
@Service
public class MemberService {

    private static final Logger LOG = LoggerFactory.getLogger(MemberService.class);

    @Resource
    private MemberMapper memberMapper;

    public int count() {
        return Math.toIntExact(memberMapper.countByExample(null));
    }

    /**
     * 注册
     * @param req
     * @return
     */
    public long register(MemberRegisterReq req){
        String mobile = req.getMobile();
        //判断手机号之前是否注册过
        Member memberDB = selectByMobile(mobile);

        if (ObjectUtil.isNotNull(memberDB)){
//            return list.get(0).getId();
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_EXEIST);
        }

        Member member = new Member();
//        member.setId(System.currentTimeMillis());
        //雪花算法
//        member.setId(IdUtil.getSnowflake(1,1).nextId());
        member.setId(SnowUtil.getSnowflakeNextId());
        member.setMobile(mobile);
        memberMapper.insert(member);
        return member.getId();
    }

    /**
     * 会员未注册则进行注册并且发送短信验证码
     * @param req
     * @return
     */
    public void sendCode(MemberSendCodeReq req){
        String mobile = req.getMobile();
        //判断手机号之前是否注册过
        Member memberDB = selectByMobile(mobile);

        // 如果手机号不存在，则插入一条记录
        if (ObjectUtil.isNull(memberDB)){
            LOG.info("机号不存在，插入一条记录");
            Member member = new Member();
            member.setId(SnowUtil.getSnowflakeNextId());
            member.setMobile(mobile);
            memberMapper.insert(member);
        }else {
            LOG.info("机号存在，不插入记录");
        }

        //生成验证码
//        String code = RandomUtil.randomString(4);
        // 为方便测试
        String code = "8888";
        LOG.info("生成短信验证码：{}",code);

        //保存短信记录表:手机号，短信验证码，有效期，是否已使用，业务类型，发送时间，使用时间
        LOG.info("保存短信记录表");

        // 对接短信通道，发送短信
        LOG.info("对接短信通道");

    }

    /**
     * 登录过程中发现未注册，提示用户先获取验证码，验证验证码是否正确
     * @param req
     * @return MemberLoginResp
     */
    public MemberLoginResp login(MemberLoginReq req){
        String mobile = req.getMobile();
        String code = req.getCode();
        Member memberDB = selectByMobile(mobile);

        if (ObjectUtil.isNull(memberDB)){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_NOT_EXEIST);
        }

        // 校验短信验证码
        if (!"8888".equals(code)){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_CODE_ERROR);
        }

        MemberLoginResp memberLoginResp = BeanUtil.copyProperties(memberDB, MemberLoginResp.class);

        // 官方Hutool工具生成token
        /*Map<String, Object> map = BeanUtil.beanToMap(memberLoginResp);
        String key = "zcl12306";
        String token = JWTUtil.createToken(map, key.getBytes());
        memberLoginResp.setToken(token);*/

        // 自定义类JwtUtil生成token
        String token = JwtUtil.createToken(memberLoginResp.getId(),memberLoginResp.getMobile());
        memberLoginResp.setToken(token);


        return memberLoginResp;
    }

    /**
     * 判断数据库中是否存在用户信息
     * @param mobile
     * @return
     */
    private Member selectByMobile(String mobile) {
        //判断手机号之前是否注册过
        MemberExample memberExample = new MemberExample();
        memberExample.createCriteria().andMobileEqualTo(mobile);
        List<Member> list = memberMapper.selectByExample(memberExample);

        if (CollUtil.isEmpty(list)){
            return null;
        }else {
            return list.get(0);
        }
    }
}
